<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en"><head><title>Draft: PubSubHubbub Core 0.4 -- Working Draft</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="description" content="PubSubHubbub Core 0.4 -- Working Draft">
<meta name="generator" content="xml2rfc v1.36 (http://xml.resource.org/)">
<style type='text/css'><!--
        body {
                font-family: verdana, charcoal, helvetica, arial, sans-serif;
                font-size: small; color: #000; background-color: #FFF;
                margin: 2em;
        }
        h1, h2, h3, h4, h5, h6 {
                font-family: helvetica, monaco, "MS Sans Serif", arial, sans-serif;
                font-weight: bold; font-style: normal;
        }
        h1 { color: #900; background-color: transparent; text-align: right; }
        h3 { color: #333; background-color: transparent; }

        td.RFCbug {
                font-size: x-small; text-decoration: none;
                width: 30px; height: 30px; padding-top: 2px;
                text-align: justify; vertical-align: middle;
                background-color: #000;
        }
        td.RFCbug span.RFC {
                font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
                font-weight: bold; color: #666;
        }
        td.RFCbug span.hotText {
                font-family: charcoal, monaco, geneva, "MS Sans Serif", helvetica, verdana, sans-serif;
                font-weight: normal; text-align: center; color: #FFF;
        }

        table.TOCbug { width: 30px; height: 15px; }
        td.TOCbug {
                text-align: center; width: 30px; height: 15px;
                color: #FFF; background-color: #900;
        }
        td.TOCbug a {
                font-family: monaco, charcoal, geneva, "MS Sans Serif", helvetica, sans-serif;
                font-weight: bold; font-size: x-small; text-decoration: none;
                color: #FFF; background-color: transparent;
        }

        td.header {
                font-family: arial, helvetica, sans-serif; font-size: x-small;
                vertical-align: top; width: 33%;
                color: #FFF; background-color: #666;
        }
        td.author { font-weight: bold; font-size: x-small; margin-left: 4em; }
        td.author-text { font-size: x-small; }

        /* info code from SantaKlauss at http://www.madaboutstyle.com/tooltip2.html */
        a.info {
                /* This is the key. */
                position: relative;
                z-index: 24;
                text-decoration: none;
        }
        a.info:hover {
                z-index: 25;
                color: #FFF; background-color: #900;
        }
        a.info span { display: none; }
        a.info:hover span.info {
                /* The span will display just on :hover state. */
                display: block;
                position: absolute;
                font-size: smaller;
                top: 2em; left: -5em; width: 15em;
                padding: 2px; border: 1px solid #333;
                color: #900; background-color: #EEE;
                text-align: left;
        }

        a { font-weight: bold; }
        a:link    { color: #900; background-color: transparent; }
        a:visited { color: #633; background-color: transparent; }
        a:active  { color: #633; background-color: transparent; }

        p { margin-left: 2em; margin-right: 2em; }
        p.copyright { font-size: x-small; }
        p.toc { font-size: small; font-weight: bold; margin-left: 3em; }
        table.toc { margin: 0 0 0 3em; padding: 0; border: 0; vertical-align: text-top; }
        td.toc { font-size: small; font-weight: bold; vertical-align: text-top; }

        ol.text { margin-left: 2em; margin-right: 2em; }
        ul.text { margin-left: 2em; margin-right: 2em; }
        li      { margin-left: 3em; }

        /* RFC-2629 <spanx>s and <artwork>s. */
        em     { font-style: italic; }
        strong { font-weight: bold; }
        dfn    { font-weight: bold; font-style: normal; }
        cite   { font-weight: normal; font-style: normal; }
        tt     { color: #036; }
        tt, pre, pre dfn, pre em, pre cite, pre span {
                font-family: "Courier New", Courier, monospace; font-size: small;
        }
        pre {
                text-align: left; padding: 4px;
                color: #000; background-color: #CCC;
        }
        pre dfn  { color: #900; }
        pre em   { color: #66F; background-color: #FFC; font-weight: normal; }
        pre .key { color: #33C; font-weight: bold; }
        pre .id  { color: #900; }
        pre .str { color: #000; background-color: #CFF; }
        pre .val { color: #066; }
        pre .rep { color: #909; }
        pre .oth { color: #000; background-color: #FCF; }
        pre .err { background-color: #FCC; }

        /* RFC-2629 <texttable>s. */
        table.all, table.full, table.headers, table.none {
                font-size: small; text-align: center; border-width: 2px;
                vertical-align: top; border-collapse: collapse;
        }
        table.all, table.full { border-style: solid; border-color: black; }
        table.headers, table.none { border-style: none; }
        th {
                font-weight: bold; border-color: black;
                border-width: 2px 2px 3px 2px;
        }
        table.all th, table.full th { border-style: solid; }
        table.headers th { border-style: none none solid none; }
        table.none th { border-style: none; }
        table.all td {
                border-style: solid; border-color: #333;
                border-width: 1px 2px;
        }
        table.full td, table.headers td, table.none td { border-style: none; }

        hr { height: 1px; }
        hr.insert {
                width: 80%; border-style: none; border-width: 0;
                color: #CCC; background-color: #CCC;
        }
--></style>
</head>
<body>
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<table summary="layout" width="66%" border="0" cellpadding="0" cellspacing="0"><tr><td><table summary="layout" width="100%" border="0" cellpadding="2" cellspacing="1">
<tr><td class="header">Draft</td><td class="header">B. Fitzpatrick</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">B. Slatkin</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">Google, Inc</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">M. Atkins</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">Six Apart Ltd.</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">J. Genestoux</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">Notifixious Inc.</td></tr>
<tr><td class="header">&nbsp;</td><td class="header">June 20, 2013</td></tr>
</table></td></tr></table>
<h1><br />PubSubHubbub Core 0.4 -- Working Draft</h1>

<h3>Abstract</h3>

<p>An open, simple, web-scale and decentralized pubsub protocol.
          Anybody can play.
</p>
<p>As opposed to more developed (and more complex) pubsub specs like <a class='info' href='#XEP-0060'>Jabber Publish-Subscribe<span> (</span><span class='info'>Millard, P., Saint-Andre, P., and R. Meijer, &ldquo;Publish-Subscribe,&rdquo; .</span><span>)</span></a> [XEP&#8209;0060] this spec's base profile
      (the barrier-to-entry to speak it) is dead simple. The fancy bits required
      for high-volume publishers and subscribers are optional. The base profile
      is HTTP-based, as opposed to XMPP (see more on this below).
</p>
<p>To dramatically simplify this spec in several places where we had to
      choose between supporting A or B, we took it upon ourselves to say "only
      A", rather than making it an implementation decision.
</p>
<p>We offer this spec in hopes that it fills a need or at least advances
      the state of the discussion in the pubsub space. Polling sucks. We think
      a decentralized pubsub layer is a fundamental, missing layer in the
      Internet architecture today and its existence, more than just enabling
      the obvious lower latency feed readers, would enable many cool
      applications, most of which we can't even imagine. But we're looking
      forward to decentralized social networking.
</p><a name="toc"></a><br /><hr />
<h3>Table of Contents</h3>
<p class="toc">
<a href="#anchor1">1.</a>&nbsp;
Notation and Conventions<br />
<a href="#anchor2">2.</a>&nbsp;
Definitions<br />
<a href="#anchor3">3.</a>&nbsp;
High-level protocol flow<br />
<a href="#discovery">4.</a>&nbsp;
Discovery<br />
<a href="#subscribing">5.</a>&nbsp;
Subscribing and Unsubscribing<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#anchor4">5.1.</a>&nbsp;
Subscriber Sends Subscription Request<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#validationsub">5.2.</a>&nbsp;
Subscription Validation<br />
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#verifysub">5.3.</a>&nbsp;
Hub Verifies Intent of the Subscriber<br />
<a href="#publishing">6.</a>&nbsp;
Publishing<br />
<a href="#contentdistribution">7.</a>&nbsp;
Content Distribution<br />
<a href="#authednotify">8.</a>&nbsp;
Authenticated Content Distribution<br />
<a href="#rfc.references1">9.</a>&nbsp;
References<br />
<a href="#anchor9">Appendix&nbsp;A.</a>&nbsp;
Specification Feedback<br />
<a href="#rfc.authors">&#167;</a>&nbsp;
Authors' Addresses<br />
</p>
<br clear="all" />

<a name="anchor1"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.1"></a><h3>1.&nbsp;
Notation and Conventions</h3>

<p>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
      "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
      document are to be interpreted as described in <a class='info' href='#RFC2119'>[RFC2119]<span> (</span><span class='info'>Bradner, B., &ldquo;Key words for use in RFCs to Indicate Requirement           Levels,&rdquo; .</span><span>)</span></a>. Domain name examples use <a class='info' href='#RFC2606'>[RFC2606]<span> (</span><span class='info'>Eastlake, D. and A. Panitz, &ldquo;Reserved Top Level DNS Names,&rdquo; .</span><span>)</span></a>.
</p>
<a name="anchor2"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.2"></a><h3>2.&nbsp;
Definitions</h3>

<p></p>
<blockquote class="text"><dl>
<dt>Topic:</dt>
<dd>An <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] resource URL. The
          unit to which one can subscribe to changes. 
</dd>
<dt>Hub (&quot;the hub&quot;):</dt>
<dd>The server (<a class='info' href='#RFC3986'>URL<span> (</span><span class='info'>Berners-Lee, T., &ldquo;Uniform Resource Identifiers (URI): Generic Syntax,&rdquo; .</span><span>)</span></a> [RFC3986]) which implements both sides of this
          protocol. Any hub MAY implement its own policies on who can use it.
</dd>
<dt>Publisher:</dt>
<dd>An owner of a topic. Notifies the hub when
          the topic feed has been updated. As in almost all pubsub systems, the
          publisher is unaware of the subscribers, if any. Other pubsub systems
          might call the publisher the "source".
</dd>
<dt>Subscriber:</dt>
<dd>An entity (person or program) that wants
          to be notified of changes on a topic. The subscriber must be
          directly network-accessible and is identified by its Subscriber
          Callback URL.
</dd>
<dt>Subscription:</dt>
<dd>A unique relation to a topic by a
          subscriber that indicates it should receive updates for that topic. A
          subscription's unique key is the tuple (Topic URL, Subscriber Callback
          URL). Subscriptions may (at the hub's decision) have expiration times
          akin to DHCP leases which must be periodically renewed.
</dd>
<dt>Subscriber Callback URL:</dt>
<dd>The <a class='info' href='#RFC3986'>URL<span> (</span><span class='info'>Berners-Lee, T., &ldquo;Uniform Resource Identifiers (URI): Generic Syntax,&rdquo; .</span><span>)</span></a> [RFC3986] at which a subscriber wishes to receive
          notifications.
</dd>
<dt>Event:</dt>
<dd>An event that causes updates to multiple topics.
          For each event that happens (e.g. "Brad posted to the Linux
          Community."), multiple topics could be affected (e.g. "Brad posted."
          and "Linux community has new post"). Publisher events cause topics to
          be updated and the hub looks up all subscriptions for affected topics,
          sending out notifications to subscribers.
</dd>
<dt>Notification:</dt>
<dd>A payload describing how a topic's
          contents have changed, or the full updated content.
          Depending on the topic's content type, the difference (or "delta") may be
          computed by the hub and sent to all subscribers.
</dd>
</dl></blockquote>

<a name="anchor3"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.3"></a><h3>3.&nbsp;
High-level protocol flow</h3>

<p>(This section is non-normative.)
</p>
<p></p>
<ul class="text">
<li>Publishers notify their hub(s) URLs when their topic(s)
          change.
</li>
<li>Subscribers POST to one or more of the advertised hubs for a
          topic they're interested in. Alternatively, some hubs may offer
          auto-polling capability, to let {their,any} subscribers subscribe to
          topics which don't advertise a hub.
</li>
<li>The hub caches minimal metadata (id, data, entry digest) about
          each topic's previous state. When the hub re-fetches a topic feed (on
          its own initiative or as a result of a publisher's ping) and finds a
          delta, it enqueues a notification to all registered subscribers.
</li>
</ul>

<a name="discovery"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.4"></a><h3>4.&nbsp;
Discovery</h3>

<p>A potential subscriber initiates discovery by retrieving (GET or HEAD request)
      the topic to which it wants to subscribe. The <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] response from the publisher MUST
      include at least one <a class='info' href='#RFC5988'>Link Header<span> (</span><span class='info'>Nottingham, M., &ldquo;Web Linking,&rdquo; October&nbsp;2010.</span><span>)</span></a> [RFC5988] with
      <tt>rel=hub</tt> (a hub link header) as well as exactly one <a class='info' href='#RFC5988'>Link Header<span> (</span><span class='info'>Nottingham, M., &ldquo;Web Linking,&rdquo; October&nbsp;2010.</span><span>)</span></a> [RFC5988]
      with <tt>rel=self</tt> (the self link header).
      The former MUST indicate the exact URL of a PubSubHubbub hub designated by the publisher.
      If more than one URL is specified, it is expected that the publisher pings each
      of these URLs, so the subscriber may subscribe to one or more of these.
      The latter will point to the permanent URL for the resource being polled.
</p>
<p>In the absence of <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] Link headers, subscribers MAY fall back to
     other methods to discover the hub(s) and the canonical URI of the topic.
     If the topic is an XML based feed, it MAY use embedded link elements
     as described in Appendix B of <a class='info' href='#RFC5988'>Web Linking<span> (</span><span class='info'>Nottingham, M., &ldquo;Web Linking,&rdquo; October&nbsp;2010.</span><span>)</span></a> [RFC5988].
     Similarly, for HTML pages, it MAY use embedded link elements as described
     in Appendix A of <a class='info' href='#RFC5988'>Web Linking<span> (</span><span class='info'>Nottingham, M., &ldquo;Web Linking,&rdquo; October&nbsp;2010.</span><span>)</span></a> [RFC5988]. Finally, publishers
     MAY also use the <a class='info' href='#RFC5785'>Well-Known Uniform Resource Identifiers<span> (</span><span class='info'>Nottingham, M. and E. Hammer-Lahav, &ldquo;Defining Well-Known Uniform Resource Identifiers (URIs),&rdquo; .</span><span>)</span></a> [RFC5785]
     .host-meta to include the &lt;Link&gt; element with rel="hub".
</p>
<a name="subscribing"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5"></a><h3>5.&nbsp;
Subscribing and Unsubscribing</h3>

<p>Subscribing to a topic URL consists of four parts that may occur
      immediately in sequence or have a delay.
</p>
<p></p>
<ul class="text">
<li>Requesting a subscription using the hub
</li>
<li>Validating the subscription with the publisher (OPTIONAL)
</li>
<li>Confirming the subscription was actually desired by the subscriber
</li>
<li>Periodically reconfirming the subscription is still active (OPTIONAL)
</li>
</ul>

<p>Unsubscribing works in the same way, except with a single parameter
      changed to indicate the desire to unsubscribe. Also, the Hub will not validate
      unsubscription requests with the publisher.
</p>
<a name="anchor4"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5.1"></a><h3>5.1.&nbsp;
Subscriber Sends Subscription Request</h3>

<p>Subscription is initiated by the subscriber making an <a class='info' href='#RFC2616'>HTTPS<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616]
        or <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] POST request to the hub URL. This request
        has a Content-Type of <tt>application/x-www-form-urlencoded</tt> (described in
        Section 17.13.4 of <a class='info' href='#W3C.REC-html401-19991224'>[W3C.REC&#8209;html401&#8209;19991224]<span> (</span><span class='info'>Raggett, D., Hors, A., and I. Jacobs, &ldquo;HTML 4.01 Specification,&rdquo; December&nbsp;1999.</span><span>)</span></a>) and the
        following parameters in its body:
</p>
<p></p>
<blockquote class="text"><dl>
<dt>hub.callback</dt>
<dd>REQUIRED. The subscriber's callback URL
            where notifications should be delivered. It is considered good practice
            to use a unique callback URL for each subscription.
</dd>
<dt>hub.mode</dt>
<dd>REQUIRED. The literal string "subscribe" or
            "unsubscribe", depending on the goal of the request.
</dd>
<dt>hub.topic</dt>
<dd>REQUIRED. The topic URL that the subscriber
            wishes to subscribe to or unsubscribe from.
</dd>
<dt>hub.lease_seconds</dt>
<dd>OPTIONAL. Number of seconds for
            which the subscriber would like to have the subscription active. Hubs MAY
            choose to respect this value or not, depending on their own policies.
            This parameter MAY be present for unsubscription requests and MUST be
            ignored by the hub in that case.
</dd>
<dt>hub.secret</dt>
<dd>OPTIONAL. A subscriber-provided secret
            string that will be used to compute an HMAC digest for <a class='info' href='#authednotify'>authorized content distribution<span> (</span><span class='info'>Authenticated Content Distribution</span><span>)</span></a>. If not
            supplied, the HMAC digest will not be present for content
            distribution requests. This parameter SHOULD only be specified when
            the request was made over <a class='info' href='#RFC2818'>HTTPS<span> (</span><span class='info'>Rescorla, E., &ldquo;HTTP Over TLS,&rdquo; May&nbsp;2000.</span><span>)</span></a> [RFC2818]. This
            parameter MUST be less than 200 bytes in length.
</dd>
</dl></blockquote>

<p>Subscribers MAY also include additional <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] request parameters, as well
          as <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] Headers if they are required by the hub.
          In the context of social web applications, it is considered good
          practice to include a From <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] header (as described in section 14.22
          of <a class='info' href='#RFC2616'>Hypertext Transfer Protocol<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616]) to indicate
          on behalf of which user the subscription is being performed.
          
</p>
<p>Hubs MUST ignore additional request parameters they do not
          understand.
</p>
<p>Hubs MUST allow subscribers to re-request subscriptions that are
          already activated. Each subsequent request to a hub to subscribe or
          unsubscribe MUST override the previous subscription state for a
          specific topic URL and callback URL combination once the action is
          verified. Any failures to confirm the subscription action MUST leave
          the subscription state unchanged. This is required so subscribers can
          renew their subscriptions before the lease seconds period is over
          without any interruption.
</p>
<a name="anchor5"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5.1.1"></a><h3>5.1.1.&nbsp;
Subscription Parameter Details</h3>

<p>The topic and callback URLs MAY use <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616]
          or <a class='info' href='#RFC2818'>HTTPS<span> (</span><span class='info'>Rescorla, E., &ldquo;HTTP Over TLS,&rdquo; May&nbsp;2000.</span><span>)</span></a> [RFC2818] schemes. The topic URL MUST
          be the one advertised by the publisher in a Self Link Header
          during the discovery phase. (See <a class='info' href='#discovery'>Section&nbsp;4<span> (</span><span class='info'>Discovery</span><span>)</span></a>).
          Hubs MAY refuse subscriptions if the topic URL does not correspond to the one
          advertised by the publisher. The topic URL can otherwise be free-form
          following <a class='info' href='#RFC3986'>the URI spec<span> (</span><span class='info'>Berners-Lee, T., &ldquo;Uniform Resource Identifiers (URI): Generic Syntax,&rdquo; .</span><span>)</span></a> [RFC3986]. Hubs MUST always
          decode non-reserved characters for these URL parameters; see section 2.4 on
          <em>"When to Encode or Decode"</em> in <a class='info' href='#RFC3986'>the URI spec<span> (</span><span class='info'>Berners-Lee, T., &ldquo;Uniform Resource Identifiers (URI): Generic Syntax,&rdquo; .</span><span>)</span></a> [RFC3986].
</p>
<p>The callback URL MAY contain arbitrary query string parameters
          (e.g., <tt>?foo=bar&amp;red=fish</tt>). Hubs MUST
          preserve the query string during subscription verification by
          appending new parameters to the end of the list using the <tt>&amp;</tt> (ampersand) character to join. Existing
          parameters with names that overlap with those used by verification
          requests will not be overwritten. For event notification, the
          callback URL will be POSTed to including any query-string parameters
          in the URL portion of the request, not as POST body parameters.
</p>
<a name="anchor6"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5.1.2"></a><h3>5.1.2.&nbsp;
Subscription Response Details</h3>

<p>The hub MUST respond to a subscription request with an <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] 202 "Accepted"
          response to indicate that the request was received and will now
          be verified (<a class='info' href='#verifysub'>Section&nbsp;5.3<span> (</span><span class='info'>Hub Verifies Intent of the Subscriber</span><span>)</span></a>) and validated (<a class='info' href='#validationsub'>Section&nbsp;5.2<span> (</span><span class='info'>Subscription Validation</span><span>)</span></a>) by the hub. The hub SHOULD perform the
          verification and validation of intent as soon as possible.
</p>
<p>If a hub finds any errors in the subscription request, an
          appropriate <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] error response code (4xx or 5xx) MUST be returned. In
          the event of an error, hubs SHOULD return a description of the error
          in the response body as plain text. Hubs MAY decide to reject some
          callback URLs or topic URLs based on their own policies (e.g., domain
          authorization, topic URL port numbers).
</p>
<a name="validationsub"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5.2"></a><h3>5.2.&nbsp;
Subscription Validation</h3>

<p>Subscriptions MAY be validated by the Hubs who may require
          more details to accept or refuse a subscription. The Hub MAY also
          check with the publisher whether the subscription should be accepted.
</p>
<p>If (and when), the subscription is accepted, the hub MUST perform the <a class='info' href='#verifysub'>verification of intent<span> (</span><span class='info'>Hub Verifies Intent of the Subscriber</span><span>)</span></a> of the subscriber. 
</p>
<p>If (and when), the subscription is denied, the hub MUST inform the subscriber
          by sending an <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] GET request to the subscriber's
          callback URL as given in the subscription request. This request has the following
          query string arguments appended (format described in Section 17.13.4 of
          <a class='info' href='#W3C.REC-html401-19991224'>[W3C.REC&#8209;html401&#8209;19991224]<span> (</span><span class='info'>Raggett, D., Hors, A., and I. Jacobs, &ldquo;HTML 4.01 Specification,&rdquo; December&nbsp;1999.</span><span>)</span></a>):
</p>
<p></p>
<blockquote class="text"><dl>
<dt>hub.mode</dt>
<dd>REQUIRED. The literal string "denied".
</dd>
<dt>hub.topic</dt>
<dd>REQUIRED. The topic URL given in the corresponding
            subscription request.
</dd>
<dt>hub.reason</dt>
<dd>OPTIONAL. The hub may include a reason
            for which the subscription has been denied.
</dd>
</dl></blockquote>

<p>Hubs may provide an additional <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] Location header (as described in section 14.30
          of <a class='info' href='#RFC2616'>Hypertext Transfer Protocol<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616]) to indicate that the
          subscriber may retry subscribing to a different hub.topic. This allows
          for limited distribution to specific groups or users in the context of social web
          applications.
</p>
<p>The subscription MAY be denied by the hub at any point (even
          if it was previously accepted). The Subscriber SHOULD then consider that
          the subscription is not possible anymore.
</p>
<a name="verifysub"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5.3"></a><h3>5.3.&nbsp;
Hub Verifies Intent of the Subscriber</h3>

<p>In order to prevent an attacker from creating unwanted subscriptions
        on behalf of a subscriber (or unsubscribing desired ones), a hub must
        ensure that the subscriber did indeed send the subscription request.
</p>
<p>The hub verifies a subscription request by sending an <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] GET request to the subscriber's callback
        URL as given in the subscription request. This request has the following
        query string arguments appended (format described in Section 17.13.4 of
        <a class='info' href='#W3C.REC-html401-19991224'>[W3C.REC&#8209;html401&#8209;19991224]<span> (</span><span class='info'>Raggett, D., Hors, A., and I. Jacobs, &ldquo;HTML 4.01 Specification,&rdquo; December&nbsp;1999.</span><span>)</span></a>):
</p>
<p></p>
<blockquote class="text"><dl>
<dt>hub.mode</dt>
<dd>REQUIRED. The literal string "subscribe" or
            "unsubscribe", which matches the original request to the hub from
            the subscriber.
</dd>
<dt>hub.topic</dt>
<dd>REQUIRED. The topic URL given in the
            corresponding subscription request.
</dd>
<dt>hub.challenge</dt>
<dd>REQUIRED. A hub-generated, random string
            that MUST be echoed by the subscriber to verify the
            subscription.
</dd>
<dt>hub.lease_seconds</dt>
<dd>REQUIRED/OPTIONAL. The
            hub-determined number of seconds that the subscription will stay
            active before expiring, measured from the time the verification
            request was made from the hub to the subscriber. Hubs MUST supply
            this parameter for subscription requests. This parameter MAY be
            present for unsubscribe requests and MUST be ignored by subscribers
            during unsubscription.
</dd>
</dl></blockquote>

<a name="anchor7"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.5.3.1"></a><h3>5.3.1.&nbsp;
Verification Details</h3>

<p>The subscriber MUST confirm that the <tt>hub.topic
          </tt> corresponds to a pending subscription or unsubscription that it
          wishes to carry out. If so, the subscriber MUST respond with an HTTP
          success (2xx) code with a response body equal to the <tt>hub.challenge</tt> parameter. If the subscriber does
          not agree with the action, the subscriber MUST respond with a 404 "Not
          Found" response.
</p>
<p>The hub MUST consider other server response codes (3xx, 4xx, 5xx)
          to mean that the verification request has failed. If the subscriber
          returns an <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] success (2xx) but the content body does not match the
          <tt>hub.challenge</tt> parameter, the hub MUST also
          consider verification to have failed.
</p>
<p>Hubs MAY make the <tt>hub.lease_seconds</tt>
          equal to the value the subscriber passed in their subscription
          request but MAY change the value depending on the hub's policies. To
          sustain a subscription, the subscriber MUST re-request the
          subscription on the hub before <tt>hub.lease_seconds</tt> seconds has elapsed.
</p>
<a name="publishing"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.6"></a><h3>6.&nbsp;
Publishing</h3>

<p>The publisher MUST inform the hubs it previously designated when a topic
      has been updated. The hub and the publisher can agree on any mechanism, as
      long as the hub is eventually able send the updated payload to the
      subscribers.
</p>
<a name="contentdistribution"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.7"></a><h3>7.&nbsp;
Content Distribution</h3>

<p>A content distribution request is an <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] POST request from hub to the subscriber's
        callback URL with the payload of the notification. This request MUST
        have a <tt>Content-Type</tt> corresponding to the
        type of the topic. The hub MAY reduce the payload to a diff between two
        consecutive versions if its format allows it.
</p>
<p>The request MUST include a <a class='info' href='#RFC5988'>Link Header<span> (</span><span class='info'>Nottingham, M., &ldquo;Web Linking,&rdquo; October&nbsp;2010.</span><span>)</span></a> [RFC5988]
        with rel=hub pointing to the Hub as well as a <a class='info' href='#RFC5988'>Link
        Header<span> (</span><span class='info'>Nottingham, M., &ldquo;Web Linking,&rdquo; October&nbsp;2010.</span><span>)</span></a> [RFC5988] with rel=self set to the topic that's being updated. The Hub
        SHOULD combine both headers into a single <a class='info' href='#RFC5988'>Link
        Header<span> (</span><span class='info'>Nottingham, M., &ldquo;Web Linking,&rdquo; October&nbsp;2010.</span><span>)</span></a> [RFC5988].
</p>
<p>The successful response from the subscriber's callback URL MUST be an
        <a class='info' href='#RFC2616'>HTTP<span> (</span><span class='info'>Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;Hypertext Transfer Protocol -- HTTP/1.1,&rdquo; .</span><span>)</span></a> [RFC2616] success (2xx) code. The hub MUST consider all other subscriber
        response codes as failures; that means subscribers MUST NOT use HTTP
        redirects for moving subscriptions. The response body from the
        subscriber MUST be ignored by the hub. Hubs SHOULD retry notifications
        repeatedly until successful (up to some reasonable maximum over a
        reasonable time period). Subscribers SHOULD respond to notifications as
        quickly as possible; their success response code SHOULD only indicate
        receipt of the message, not acknowledgment that it was successfully
        processed by the subscriber.
</p>
<a name="authednotify"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.8"></a><h3>8.&nbsp;
Authenticated Content Distribution</h3>

<p>If the subscriber supplied a value for <tt>hub.secret</tt> in their subscription request, the hub
        MUST generate an HMAC signature of the payload and include that
        signature in the request headers of the content distribution request.
        The <tt>X-Hub-Signature</tt> header's value MUST be
        in the form <tt>sha1=signature</tt> where <tt>signature</tt> is a 40-byte, hexadecimal representation
        of a <a class='info' href='#RFC3174'>SHA1 signature<span> (</span><span class='info'>Eastlake, D. and P. Jones, &ldquo;US Secure Hash Algorithm 1 (SHA1),&rdquo; September&nbsp;2001.</span><span>)</span></a> [RFC3174]. The signature MUST be
        computed using the <a class='info' href='#RFC2104'>HMAC algorithm<span> (</span><span class='info'>Krawczyk, H., Bellare, M., and R. Canetti, &ldquo;HMAC: Keyed-Hashing for Message Authentication,&rdquo; .</span><span>)</span></a> [RFC2104] with the
        request body as the data and the <tt>hub.secret</tt>
        as the key.
</p>
<p>When subscribers receive a content distribution request with the
        <tt>X-Hub-Signature</tt> header specified, they
        SHOULD recompute the SHA1 signature with the shared secret using the
        same method as the hub. If the signature does not match, subscribers
        MUST still return a 2xx success response to acknowledge receipt, but
        locally ignore the message as invalid. Using this technique along with
        <a class='info' href='#RFC2818'>HTTPS<span> (</span><span class='info'>Rescorla, E., &ldquo;HTTP Over TLS,&rdquo; May&nbsp;2000.</span><span>)</span></a> [RFC2818] for subscription requests enables
        simple subscribers to receive authenticated notifications from hubs
        without the need for subscribers to run an <a class='info' href='#RFC2818'>HTTPS<span> (</span><span class='info'>Rescorla, E., &ldquo;HTTP Over TLS,&rdquo; May&nbsp;2000.</span><span>)</span></a> [RFC2818]
        server.
</p>
<p>Please note however that this signature only ensures that the payload
        was not forged. Since the notification also includes headers, these should
        not be considered as safe by the subscriber, unless of course the subscriber
        uses <a class='info' href='#RFC2818'>HTTPS<span> (</span><span class='info'>Rescorla, E., &ldquo;HTTP Over TLS,&rdquo; May&nbsp;2000.</span><span>)</span></a> [RFC2818] callbacks.
</p>
<a name="rfc.references1"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<h3>9.&nbsp;References</h3>
<table width="99%" border="0">
<tr><td class="author-text" valign="top"><a name="RFC2104">[RFC2104]</a></td>
<td class="author-text">Krawczyk, H., Bellare, M., and R. Canetti, &ldquo;<a href="http://tools.ietf.org/html/rfc2104">HMAC: Keyed-Hashing for Message Authentication</a>,&rdquo; RFC&nbsp;2104.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2119">[RFC2119]</a></td>
<td class="author-text">Bradner, B., &ldquo;<a href="http://tools.ietf.org/html/rfc2119">Key words for use in RFCs to Indicate Requirement
          Levels</a>,&rdquo; RFC&nbsp;2119.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2606">[RFC2606]</a></td>
<td class="author-text">Eastlake, D. and A. Panitz, &ldquo;<a href="http://tools.ietf.org/html/rfc2606">Reserved Top Level DNS Names</a>,&rdquo; RFC&nbsp;2606.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2616">[RFC2616]</a></td>
<td class="author-text">Fielding, R., Gettys, J., Mogul, J., Frystyk, H., Masinter, L., Leach, P., and T. Berners-Lee, &ldquo;<a href="http://tools.ietf.org/html/rfc2616">Hypertext Transfer Protocol -- HTTP/1.1</a>,&rdquo; RFC&nbsp;2616.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC2818">[RFC2818]</a></td>
<td class="author-text">Rescorla, E., &ldquo;<a href="http://tools.ietf.org/html/rfc2818">HTTP Over TLS</a>,&rdquo; RFC&nbsp;2818, May&nbsp;2000 (<a href="ftp://ftp.isi.edu/in-notes/rfc2818.txt">TXT</a>).</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC3174">[RFC3174]</a></td>
<td class="author-text">Eastlake, D. and P. Jones, &ldquo;<a href="http://tools.ietf.org/html/rfc3174">US Secure Hash Algorithm 1 (SHA1)</a>,&rdquo; RFC&nbsp;3174, September&nbsp;2001 (<a href="ftp://ftp.isi.edu/in-notes/rfc3174.txt">TXT</a>).</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC3986">[RFC3986]</a></td>
<td class="author-text">Berners-Lee, T., &ldquo;<a href="http://tools.ietf.org/html/rfc3986">Uniform Resource Identifiers (URI): Generic Syntax</a>,&rdquo; RFC&nbsp;3986.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC5785">[RFC5785]</a></td>
<td class="author-text">Nottingham, M. and E. Hammer-Lahav, &ldquo;<a href="http://tools.ietf.org/html/rfc5785">Defining Well-Known Uniform Resource Identifiers (URIs)</a>,&rdquo; RFC&nbsp;5785.</td></tr>
<tr><td class="author-text" valign="top"><a name="RFC5988">[RFC5988]</a></td>
<td class="author-text">Nottingham, M., &ldquo;<a href="http://tools.ietf.org/html/rfc5988">Web Linking</a>,&rdquo; RFC&nbsp;5988, October&nbsp;2010 (<a href="http://tools.ietf.org/rfc/rfc5988.txt">TXT</a>).</td></tr>
<tr><td class="author-text" valign="top"><a name="W3C.REC-html401-19991224">[W3C.REC-html401-19991224]</a></td>
<td class="author-text">Raggett, D., Hors, A., and I. Jacobs, &ldquo;<a href="http://www.w3.org/TR/1999/REC-html401-19991224">HTML 4.01 Specification</a>,&rdquo; World Wide Web Consortium Recommendation&nbsp;REC-html401-19991224, December&nbsp;1999 (<a href="http://www.w3.org/TR/1999/REC-html401-19991224">HTML</a>).</td></tr>
<tr><td class="author-text" valign="top"><a name="XEP-0060">[XEP-0060]</a></td>
<td class="author-text">Millard, P., Saint-Andre, P., and R. Meijer, &ldquo;<a href="http://www.xmpp.org/extensions/xep-0060.html">Publish-Subscribe</a>,&rdquo; XSF XEP&nbsp;0060.</td></tr>
</table>

<a name="anchor9"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<a name="rfc.section.A"></a><h3>Appendix A.&nbsp;
Specification Feedback</h3>

<p>Feedback on this specification is welcomed via the
      PubSubHubbub W3C Community Group.  For
      more information, see <a href='http://www.w3.org/community/pubsub/'>the
      W3C PubSubHubbub Community Group</a>.
      
</p>
<a name="rfc.authors"></a><br /><hr />
<table summary="layout" cellpadding="0" cellspacing="2" class="TOCbug" align="right"><tr><td class="TOCbug"><a href="#toc">&nbsp;TOC&nbsp;</a></td></tr></table>
<h3>Authors' Addresses</h3>
<table width="99%" border="0" cellpadding="0" cellspacing="0">
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Brad Fitzpatrick</td></tr>
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Google, Inc</td></tr>
<tr><td class="author" align="right">Email:&nbsp;</td>
<td class="author-text"><a href="mailto:brad@danga.com">brad@danga.com</a></td></tr>
<tr cellpadding="3"><td>&nbsp;</td><td>&nbsp;</td></tr>
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Brett Slatkin</td></tr>
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Google, Inc</td></tr>
<tr><td class="author" align="right">Email:&nbsp;</td>
<td class="author-text"><a href="mailto:bslatkin@gmail.com">bslatkin@gmail.com</a></td></tr>
<tr cellpadding="3"><td>&nbsp;</td><td>&nbsp;</td></tr>
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Martin Atkins</td></tr>
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Six Apart Ltd.</td></tr>
<tr><td class="author" align="right">Email:&nbsp;</td>
<td class="author-text"><a href="mailto:mart@degeneration.co.uk">mart@degeneration.co.uk</a></td></tr>
<tr cellpadding="3"><td>&nbsp;</td><td>&nbsp;</td></tr>
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Julien Genestoux</td></tr>
<tr><td class="author-text">&nbsp;</td>
<td class="author-text">Notifixious Inc.</td></tr>
<tr><td class="author" align="right">Email:&nbsp;</td>
<td class="author-text"><a href="mailto:julien@superfeedr.com">julien@superfeedr.com</a></td></tr>
</table>
<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
try {
var pageTracker = _gat._getTracker("UA-7156573-1");
pageTracker._trackPageview();
} catch(err) {}</script>
</body></html>
